package com.qf.coupon2203.getcoupon.controller;
import cn.hutool.core.util.RandomUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qf.coupon2203.domain.constants.Constants;
import com.qf.coupon2203.domain.entity.Coupon;
import com.qf.coupon2203.domain.vo.ResultVo;
import com.qf.coupon2203.getcoupon.feign.CouponClient;
import com.qf.coupon2203.getcoupon.feign.GentokenClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/grob")
public class GetCouponController {

    @Autowired
     GentokenClient gentokenClient;

    @Autowired
    CouponClient couponClient;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @GetMapping("/coupon")
    public ResultVo grobCoupon(String name, String phone) throws Exception {

        String token = gentokenClient.getToken(phone);

        if(token == null){

            return ResultVo.error();
        }

        //1.获取redis中coupon list的长度
        int size = redisTemplate.opsForList().size(Constants.COUPON_LIST).intValue();

        //2.随机生成一个index，用来随机抽中优惠卷
        int index = RandomUtil.randomInt(0, size);

        Coupon coupon = (Coupon) redisTemplate.opsForList().index(Constants.COUPON_LIST, index);

        if(coupon.getStatus() != 0){
            return ResultVo.error("抢票失败！");
        }

        //3.抢票成功将coupon的属性状态改为1
        coupon.setStatus(1);

        //3.1如果抢票成功后，更新redis中的数据
        redisTemplate.opsForList().set(Constants.COUPON_LIST,index,coupon);


        //3.2更新数据库中的coupon状态数据
        String s = couponClient.updateCouponStatus(coupon);

        if(!s.equals("ok")){
            throw new Exception("优惠卷状态更新失败");
        }


        //4.将抢票流水到rabbitmq的水流消息队列，然后将流水写入elasticsearch
        String message = name + ":" + phone + ":" + coupon.getId();

        rabbitTemplate.convertAndSend(Constants.UPDATEDATABASE,Constants.UPDATDATABASEROUNTINGKEY,message);


        //5.将用户和优惠卷的关联表发送到消息队列然后写入到数据库

        String msg = couponClient.insertUserCoupon(name, phone, coupon.getId());

        if(!"ok".equals(msg)){
            throw new Exception("用户和优惠券关联表写入失败");
        }


        //6.将用户和优惠卷的关联表写入到redis  key 为 name:phone value为couponId

        String key = name + ":" + phone;

        String value = coupon.getId();

        redisTemplate.opsForValue().set(key,value);


        return ResultVo.ok();
    }
}
